#include "blisp.h"

static void initType(void)
{
	/* Type type object :P */
	Type_t.type = TTYPE; /* self-referential -- type is a type */
	Type_t.eval = Type_eval;
	Type_t.to_cstr = Type_to_cstr;
	Type_t.equal = Type_equal;
}

static void initNil(void)
{
	/* Nil object */
	memset(&Nil_o, 0, sizeof(Nil_o));
	Nil_o.type = TNIL;

	/* Nil type object */
	Nil_t.type = TTYPE;
	Nil_t.eval = Nil_eval;
	Nil_t.to_cstr = Nil_to_cstr;
	Nil_t.equal = Nil_equal;
}

static void initEmpty(void)
{
	/* Empty list object */
	memset(&Empty_o, 0, sizeof(Empty_o));
	Empty_o.type = TEMPTY;

	/* Empty list type object */
	Empty_t.type = TTYPE;
	Empty_t.eval = Empty_eval;
	Empty_t.to_cstr = Empty_to_cstr;
	Empty_t.equal = Empty_equal;
}

static void initBoolean(void)
{
	/* Boolean objects (true & false) */
	True_o.type = TBOOLEAN;
	True_o.value.num = CTRUE;
	False_o.type = TBOOLEAN;
	False_o.value.num = CFALSE;

	/* Boolean type object */
	Boolean_t.type = TTYPE;
	Boolean_t.eval = Boolean_eval;
	Boolean_t.to_cstr = Boolean_to_cstr;
	Boolean_t.equal = Boolean_equal;
}

/* Init Number type object */
static void initNumber(void)
{
	Number_t.type = TTYPE;
	Number_t.eval = Number_eval;
	Number_t.to_cstr = Number_to_cstr;
	Number_t.equal = Number_equal;
}

/* Init String type object */
static void initString(void)
{
	String_t.type = TTYPE;
	String_t.eval = String_eval;
	String_t.to_cstr = String_to_cstr;
	String_t.equal = String_equal;
}

/* Init Symbol type object */
static void initSymbol(void)
{
	Symbol_t.type = TTYPE;
	Symbol_t.eval = Symbol_eval;
	Symbol_t.to_cstr = Symbol_to_cstr;
	Symbol_t.equal = Symbol_equal;
}

/* Init Pair type object */
static void initPair(void)
{
	Pair_t.type = TTYPE;
	Pair_t.eval = Pair_eval;
	Pair_t.to_cstr = Pair_to_cstr;
	Pair_t.equal = Pair_equal;
}

/* Init Function type object */
static void initFunction(void)
{
	Function_t.type = TTYPE;
	Function_t.eval = Function_eval;
	Function_t.to_cstr = Function_to_cstr;
	Function_t.equal = Function_equal;
}

/*
 * Initialize all of the types and the garbage collector
 */
void blisp_init(void)
{
	initType();
	initNil();
	initEmpty();
	initBoolean();
	initNumber();
	initString();
	initSymbol();
	initPair();
	initFunction();

	/* Interp_init(); */
	set_case_sensitive(); /* default - case matters - not typical Lisp */

	GC_INIT(); /* garbage collector */
}
